package main

import (
	"fmt"
	"sort"
	"strings"
)

// A LabelName is a key for a LabelSet or Metric.  It has a value associated
// therewith.
type LabelName string

// LabelNames is a sortable LabelName slice. In implements sort.Interface.
type LabelNames []LabelName

func (l LabelNames) Len() int {
	return len(l)
}

func (l LabelNames) Less(i, j int) bool {
	return l[i] < l[j]
}

func (l LabelNames) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}

// A LabelValue is an associated value for a LabelName.
type LabelValue string

type LabelSet map[LabelName]LabelValue

// Fingerprint provides a hash-capable representation of a Metric.
// For our purposes, FNV-1A 64-bit is used.
type Fingerprint uint64

func (f Fingerprint) String() string {
	return fmt.Sprintf("%016x", uint64(f))
}

// cache the signature of an empty label set.
var emptyLabelSignature = hashNew()

const (
	offset64 = 14695981039346656037
	prime64  = 1099511628211
)

// hashNew initializes a new fnv64a hash value.
func hashNew() uint64 {
	return offset64
}

// hashAdd adds a string to a fnv64a hash value, returning the updated hash.
func hashAdd(h uint64, s string) uint64 {
	for i := 0; i < len(s); i++ {
		h ^= uint64(s[i])
		h *= prime64
	}
	return h
}

// hashAddByte adds a byte to a fnv64a hash value, returning the updated hash.
func hashAddByte(h uint64, b byte) uint64 {
	h ^= uint64(b)
	h *= prime64
	return h
}

// Fingerprint returns the LabelSet's fingerprint.
func (ls LabelSet) Fingerprint() Fingerprint {
	return labelSetToFingerprint(ls)
}

const SeparatorByte byte = 255

// labelSetToFingerprint works exactly as LabelsToSignature but takes a LabelSet as
// parameter (rather than a label map) and returns a Fingerprint.
func labelSetToFingerprint(ls LabelSet) Fingerprint {
	if len(ls) == 0 {
		return Fingerprint(emptyLabelSignature)
	}

	labelNames := make(LabelNames, 0, len(ls))
	for labelName := range ls {
		labelNames = append(labelNames, labelName)
	}
	sort.Sort(labelNames)

	sum := hashNew()
	for _, labelName := range labelNames {
		sum = hashAdd(sum, string(labelName))
		sum = hashAddByte(sum, SeparatorByte)
		sum = hashAdd(sum, string(ls[labelName]))
		sum = hashAddByte(sum, SeparatorByte)
	}
	return Fingerprint(sum)
}

// Fingerprint returns a Metric's Fingerprint.
func (m Metric) Fingerprint() Fingerprint {
	return LabelSet(m).Fingerprint()
}

// A Metric is similar to a LabelSet, but the key difference is that a Metric is
// a singleton and refers to one and only one stream of samples.
type Metric LabelSet

// 接收一个字符串参数 命名为 input
func main() {
	var input string
	fmt.Scanln(&input)

	// 解析输入字符串
	parts := strings.SplitN(input, "{", 2)
	if len(parts) != 2 {
		fmt.Println("Invalid input format")
		return
	}

	name := parts[0]
	labelsStr := strings.TrimSuffix(parts[1], "}")

	// 初始化 LabelSet
	myset := map[string]string{"__name__": name}

	// 解析标签
	if labelsStr != "" {
		labels := strings.Split(labelsStr, ",")
		for _, label := range labels {
			kv := strings.SplitN(label, "=", 2)
			if len(kv) != 2 {
				continue
			}
			key := kv[0]
			value := strings.Trim(kv[1], "\"")
			if value != "" {
				myset[key] = value
			}
		}
	}

	// 转换为 Metric
	metric := make(Metric, len(myset))
	for k, v := range myset {
		metric[LabelName(k)] = LabelValue(v)
	}

	// 计算并打印指纹
	fp := metric.Fingerprint().String()
	fmt.Println(fp)
}
